package com.tbit.uqbike.client.service;

import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.service.impl.ParkPointInfo;
import com.tbit.uqbike.client.vo.borrow.BorrowBikeVO;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 设备service
 *
 * @author Leon
 * 2017年2月24日 下午4:09:17
 */
public interface MachineService {

    /**
     * 根据设备编号查询
     *
     * @param machineNO
     * @return
     */
    Machine getByMachineNO(String machineNO);

    /**
     * 根据设备id查询
     *
     * @param machineId
     * @return
     */
    Machine getByMachineId(Integer machineId);

    /**
     * 根据设备编号批量查询
     *
     * @param machineNOs
     * @return
     */
    List<Machine> getByMachineNOs(List<String> machineNOs);

    /**
     * 根据设备编号批量查询空闲车辆
     *
     * @param machineNOs
     * @return
     */
    List<Machine> getFreeByMachineNOs(List<String> machineNOs);

    /**
     * 根据设备编号和区域id集合批量查询正在运营的空闲车辆，排除已借车辆、占用车辆
     *
     * @param machineNOs
     * @param accountIds
     * @return
     */
    List<Machine> getFreeByMachineNOs(List<String> machineNOs, Set<Integer> accountIds);

    /**
     * 根据设备id批量查询
     *
     * @param params
     * @return
     */
    List<Machine> getByMachineIds(List<Integer> machineIds);

    /**
     * 借车
     *
     * @param serNO
     * @param userId
     * @param accountId
     * @param machineNO
     * @param ble
     * @return
     */
    BorrowBusMoney borrowBike(String serNO, User user, Integer accountId, Machine machine,
                              Boolean ble, Integer orderSource,String borrowPosLogId,Integer useWxzff);

    /**
     * 借车
     *
     * @param request
     * @param vo
     * @param serNO
     * @return
     */
    Boolean borrowBikeNew(HttpServletRequest request, BorrowBikeVO vo, String serNO);

    /**
     * 还车
     *
     * @param userId
     */
    Double returnBike(String serNO, Integer userId, Boolean ble, Point point, Integer dispatchType,
                      Boolean auto, Integer orderSource, Integer mapType, String lang, String ip, Integer secondType);

    /**
     * 终端上报开锁成功
     *
     * @param serNO
     */
    void ter_unlock(String serNO);

    /**
     * 终端上报锁车成功
     *
     * @param serNO
     */
    void ter_lock(String serNO);

    /**
     * 获取当前骑行记录
     *
     * @param userId
     * @return
     */
    RideLog getBorrowing(Integer userId);

    /**
     * 获取当前骑行订单信息
     *
     * @param userId
     * @return
     */
    RideLog getBorrowingInfo(Integer accountId, Integer userId, Integer online);

    /**
     * 查询可借设备
     *
     * @param params
     * @return
     */
    List<Machine> getCanBorrow(Integer accountId, List<String> machineNOs);

    /**
     * 更新最后状态
     *
     * @param params
     */
    void updateLastStatus(Integer machineId, Integer lastUserId);

    /**
     * 是否在停车点
     *
     * @param accountId
     * @param machineNO
     * @param point
     * @return
     */
    ParkPointInfo isInParkPoint(Integer accountId, String machineNO, Point point, Integer mapType);

    /**
     * 获取设备所属品牌
     *
     * @param machineNO
     * @return
     */
    Integer findBrandId(String machineNO);

    /**
     * 通过用户码获取
     */
    Machine getByUserCode(String userCode);

    /**
     * 单车检验是否可以借车
     *
     * @param user
     * @param userCode
     */
    void checkIsOk(User user, String userCode, Point point);

    /**
     * 单车借车
     *
     * @param user
     * @param userCode
     */
    void borrow(User user, String userCode,String borrowPosLogId);

    /**
     * 检查是否在区域
     *
     * @param userCode
     * @param point
     */
    Dispatch areaCheck(Integer userId, String userCode, Point point, Dispatch dispatch);

    void remand(User user, Integer money, Point point, Integer dispatchType, Boolean auto);

    /**
     * 检验是否支持新临时停车语音
     *
     * @param userCode
     * @return
     */
    Boolean checkNewParkVoice(String userCode);

    /**
     * 是否在道钉
     *
     * @param machineNO
     * @return
     */
    Integer isInBleBeacon(String machineNO, Integer accountId, String orderNO);

    /**
     * 是否在站点附近
     *
     * @param parkPointId
     * @param machineNO
     * @param mapType
     * @return
     */
    Boolean isNearPark(Integer parkPointId, String machineNO, Integer mapType);


    /**
     * 计算两个设备之间的距离（单位：米）
     *
     * @param machineId1
     * @param machineId2
     * @return
     */
    double calculateDistance(Integer machineId1,Integer machineId2);

    /**
     * 检测是否满足还车条件
     *
     * @param userId
     */
    void isSuccess(Integer userId, Double lon, Double lat, Integer mapType);

    /**
     * 是否支持头盔锁等功能
     *
     * @param userCode
     * @return
     */
    List<MachineFunction> isSupport(String userCode);

    /**
     * 头盔锁校验,返回调度类型
     *
     * @param machine
     * @param userId
     * @param orderNO
     * @return
     */
    Dispatch checkHelmet(Machine machine, Integer userId, String orderNO, Map<String, Object> rideMap, Integer isLast);

    /**
     * 获取角度
     *
     * @param points
     * @return
     */
    double getParkAngle(String points);

    /**
     * 垂直停车
     *
     * @param accountConfig
     * @param machine
     * @param orderNO
     * @param parkPointId
     */
    Dispatch isVertical(AccountConfig accountConfig, Machine machine, Integer userId, String orderNO,
                        Integer parkPointId, String tlvs, Integer isLast);

    /**
     * 智能头盔锁逻辑
     *
     * @param machineNO
     * @param terStatus
     * @return
     */
    Dispatch intelHelmetCheck(String machineNO, Integer terStatus);

    void handlePay(BorrowReturnTer info);

    /**
     * 获取骑行金额
     *
     * @param user         用户信息
     * @param rideLog      骑行订单信息
     * @param park         临时停车信息
     * @param dispatchType 调度类型
     * @param serNO        流水号
     * @param map          返回集合
     * @param secondType   第二调度类型
     * @param afterPay     后支付开关
     * @return
     */
    Double getMoney(User user, RideLog rideLog, Park park, Integer dispatchType, String serNO,
                    Map<String, String> map, Integer type, Integer money, Integer operatorId,
                    String operatorName, String operatorPhone, Integer secondType,Integer afterPay);

    /**
     * 扣费
     *
     * @param info 还车信息
     */
    void cash(BorrowReturnTer info);

    void addBalanceChange(User user, String orderNO, Integer accountId, Long dateTime, Integer capitalType, Integer businessType
            , Long startMoney, Long changeMoney, String remark, Integer changeType);

    /**
     * 判断是否需要拍照还车
     *
     * @param userId   用户id
     * @return true 需要拍照还车
     */
    boolean checkIsPhoto(Integer userId, RideLog rideLog, Machine machine);

    /**
     * 校验是否停运
     * @param brandId 品牌id
     * @param accountId 区域id
     */
    Boolean checkServiceSwitch(Integer brandId, Integer accountId);
}